home *** CD-ROM | disk | FTP | other *** search
- /* sect.c */
-
- /*
- * Aug-23-88 jye. Change and add codes so that can be used for MS-DOS
- * Dec-20-89 jye. Free a bug that HDX gives a error message when CD-ROM
- * is busy.
- */
-
- #include "obdefs.h"
- #include "osbind.h"
- #include "mydefs.h"
- #include "part.h"
- #include "hdx.h"
- #include "addr.h"
- #include "myerror.h"
-
- #define ZBUFSIZ 0x4000 /* about 16k == 32 sectors */
- #define ZCOUNT (ZBUFSIZ/0x200) /* ZCOUNT = 32 */
- #define MAXUNITS 16 /* max number of logical units */
-
- extern long ostack; /* old stack pointer */
- extern UWORD errcode(); /* function to return error code */
- extern int yesscan; /* the flag for the func. IBMGPART use */
- extern int npart; /* the number of partitions */
- extern int ext; /* the index of extended partition */
- extern int needscan; /* TRUE: if it is the first time to scan the units */
- extern int athead; /* the # of data heads on the AT drive */
- extern int atcyl; /* the # of cylinders on the AT drive */
- extern int atspt; /* the # of sectors per track on the AT drive */
- /*
- * Logical-to-dev+partition mapping table.
- */
- int nlogdevs; /* # logical devices */
- LOGMAP logmap[EXTRALOGD]; /* logical dev map */
- int livedevs[1]; /* live devs flags; 1: device is alive */
- int atexst; /* AT drive exists */
- int typedev = 0x0000;
- int typedrv = 0x0000;
-
-
- /*
- * Rebuild logical-to-physical mapping
- * by reading and interpreting the root
- * blocks for all physical devs.
- *
- */
-
- rescan(flag, znm)
-
- int flag; /* 0: don't report medium change error; */
- /* non-0: report medium change error; */
- int znm; /* 1: do zero & markbad; 0: do partition & format */
-
- {
- int dev=0;
- char buf[512];
- int partno, ret, i;
- PART *partinfo;
-
- ostack = Super(NULL); /* set supervice mode */
- delay();
- if ((atexst = chkat())) { /* AT drive exist */
- if ((ret = identify(dev, buf)) == OK) {
- atcyl = getword(buf+2);
- athead = getword(buf+6);
- atspt = getword(buf+12);
- } else {
- delay();
- Super(ostack);
- return ERROR;
- }
- }
- delay();
- Super(ostack);
- /* disable all logical and physical devs */
- for (dev = 0; dev < EXTRALOGD; ++dev)
- logmap[dev].lm_physdev = -1;
-
- /*
- * Scan all physical devs
- * and pick up partition structures.
- */
- nlogdevs = 0;
- dev = 0;
-
- if (getroot(dev, buf, (SECTOR)0) != 0) {
- return(ERROR);
- }
-
- livedevs[dev] = 1;
- yesscan = 1;
- if (stgpart(dev, buf, (PART *)&partinfo) == ERROR) {
- return ERROR;
- }
- if (ext != NO_EXT) {
- sortpart(partinfo,SCAN_BS);
- }
- for (partno = 0; partno < npart; ++partno) {
- if ((partinfo[partno].p_flg & P_EXISTS) &&
- (partinfo[partno].p_siz != (SECTOR)0) &&
- (((partinfo[partno].p_id[0] == 'G') &&
- (partinfo[partno].p_id[1] == 'E') &&
- (partinfo[partno].p_id[2] == 'M')) ||
- ((partinfo[partno].p_id[0] == 'B') &&
- (partinfo[partno].p_id[1] == 'G') &&
- (partinfo[partno].p_id[2] == 'M'))))
- {
- if (nlogdevs > EXTRALOGD) {
- continue;
- }
- logmap[nlogdevs].lm_physdev = dev;
- logmap[nlogdevs].lm_partno = partno;
- logmap[nlogdevs].lm_start = partinfo[partno].p_st;
- logmap[nlogdevs].lm_siz = partinfo[partno].p_siz;
- ++nlogdevs;
- }
- }
- if (partinfo > 0) Mfree(partinfo);
-
- return OK;
- }
-
- /* rerange the partition informations. */
-
- sortpart(pinfo, type)
- PART *pinfo;
- int type; /* USER_ED = 1: for user interface use */
- /* SCAN_BS = 0: for rescan() and laybs() use */
- {
- int i, j, k;
- PART rpart[2];
-
- if (ext == NO_EXT) return OK; /* don't need sort */
- for (i = 0; i < 2; i++) { /* initialize the temple space */
- rpart[i].p_flg = 0L;
- rpart[i].p_st = 0L;
- rpart[i].p_siz = 0L;
- for (k = 0; k < 3; k++)
- rpart[i].p_id[k] = '0';
- }
- /* save the partitions that after the extened partitions */
- for (i = ext+1, j=0; i < 4; i++, j++) {
- if (pinfo[i].p_flg & P_EXISTS) {
- rpart[j].p_flg = P_EXISTS;
- rpart[j].p_st = pinfo[i].p_st;
- rpart[j].p_siz = pinfo[i].p_siz;
- for (k = 0; k < 3; k++)
- rpart[j].p_id[k] = pinfo[i].p_id[k];
- }
- }
- /* move the extened partition to the front */
- for (i=4, j = ext; i < npart; i++, j++) {
- if (pinfo[i].p_flg & P_EXISTS) {
- pinfo[j].p_flg = P_EXISTS;
- pinfo[j].p_st = (type)?(pinfo[i].p_st):(pinfo[i].p_st + ROOTSECT);
- pinfo[j].p_siz = (type)?(pinfo[i].p_siz):(pinfo[i].p_siz-ROOTSECT);
- for (k = 0; k < 3; k++)
- pinfo[j].p_id[k] = pinfo[i].p_id[k];
- } else { j--;} /* stay with that space */
- }
- /* copy the not extended partitions back after the extended partitions */
- for (i=0; i < 2; i++, j++) {
- if (rpart[i].p_flg & P_EXISTS) {
- pinfo[j].p_flg = P_EXISTS;
- pinfo[j].p_st = rpart[i].p_st;
- pinfo[j].p_siz = rpart[i].p_siz;
- for (k = 0; k < 3; k++)
- pinfo[j].p_id[k] = rpart[i].p_id[k];
- } else {j--;}
- }
- for (i = j; i < npart; i++) { /* set the rest to 0 */
- pinfo[i].p_flg = 0L;
- pinfo[i].p_st = 0L;
- pinfo[i].p_siz = 0L;
- for (k = 0; k < 3; k++)
- pinfo[i].p_id[k] = '0';
- }
- }
-
-
-
- /*
- * From a PHYSICAL device unit (0->7)
- * and a partition number (0->3), figure
- * out the LOGICAL disk number ('C'->'P').
- *
- * return the LOGICAL disk number or
- * ERROR if the PHYSICAL device doesn't exist.
- *
- */
- phys2log(pdev, pno)
- int pdev; /* physical device unit */
- int pno; /* partition number (0 -> 3) */
- {
- int logdev; /* index to step through partitions of a phys unit */
-
- for (logdev = 0; logdev < EXTRALOGD; logdev++) {
- if (logmap[logdev].lm_physdev == pdev &&
- logmap[logdev].lm_partno == pno)
- return ('C'+logdev);
- }
- return ERROR;
- }
-
-
- /*
- * Map block on logical device to
- * block on physical device;
- * return ERROR if the logical device
- * doesn't exist.
- */
- log2phys(adev, ablk)
- int *adev;
- SECTOR *ablk;
- {
- int dev;
- char xbuf[256];
-
- dev = *adev;
- if (dev >= 0 && dev <= 17)
- return OK;
-
- dev = toupper(dev);
- if (dev >= 'C' && dev <=
- ('C'+EXTRALOGD)) /* from C to 't' are 50 logic device */
- {
- dev -= 'C';
- *adev = logmap[dev].lm_physdev;
- *ablk = logmap[dev].lm_start + *ablk;
- return OK;
- }
-
- return ERROR;
- }
-
-
-
- /*
- * Return physical starting block# of a partition
- *
- */
- SECTOR
- logstart(ldev)
- int ldev; /* logical device */
- {
- ldev = toupper(ldev);
- if (ldev >= 'C' && ldev <=
- ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
- ldev -= 'C';
- return (logmap[ldev].lm_start);
- }
- return ERROR;
- }
-
-
-
- /*
- * Return physical starting block# of a partition's data block.
- *
- */
- SECTOR
- logend(ldev)
- int ldev; /* logical device */
- {
- ldev = toupper(ldev);
- if (ldev >= 'C' && ldev <=
- ('C'+EXTRALOGD)){/*from C to 't' are 50 logic device */
- ldev -= 'C';
- return (logmap[ldev].lm_start+logmap[ldev].lm_siz-1);
- }
- return ERROR;
- }
-
-
- #define MFM 17 /* sectors per track for MFM */
- #define RLL 26 /* sectors per track for RLL */
-
-
-
- /*
- * Chkparm()
- * Check if given logical device has the asssumed parameters.
- * Assumptions are:
- * - 512 bytes/sector
- * - 2 sectors/cluster
- * - 1 reserved sector
- * - 2 FATs
- *
- * Input:
- * ldev - logical device number ('C' -> 'P').
- *
- * Return:
- * OK - parameters of partition match the assumptions
- * ERROR - something went wrong.
- *
- * Comment:
- * Number of FATs is assumed to be 2. Cannot check this
- * because previous version of HDX did not put that in the boot
- * sector.
- */
- chkparm(ldev)
- int ldev;
- {
- char bs[512]; /* boot sector */
- BOOT *boot; /* boot structure */
- UWORD bps, res, siz; /* bytes/sector, num reserved sectors, ldev size */
- int ret;
-
- if ((ret = rdsects(ldev, 1, bs, (SECTOR)0)) != 0) {
- goto parmend;
- }
-
- boot = (BOOT *)bs;
- gw((UWORD *)&boot->b_bps, &bps); /* what is number bytes/sector? */
- gw((UWORD *)&boot->b_res, &res); /* what is num of reserved sectors? */
- gw((UWORD *)&boot->b_nsects, &siz); /* what is size of partition */
- if (bps % BPS /* bytes per sector == ratio of 512 ? */
- || res != 1) { /* num sectors reserved == 1 ? */
- ret = ERROR; /* Nope, different from assumptions */
- goto parmend;
- }
-
- /* Check if sectors per cluster make sense */
- if (boot->b_spc != 2) {
- ret = ERROR;
- goto parmend;
- }
-
- ret = OK; /* If yes, return OK */
-
- parmend:
- return ret;
- }
-
-
- /*
- * Get dev's root block.
- *
- */
- getroot(dev, buf, sect)
- int dev;
- char *buf;
- SECTOR sect;
- {
- return rdsects(dev, 1, buf, sect);
- }
-
-
- /*
- * Put dev's root block.
- *
- */
- putroot(dev, buf, sect)
- int dev;
- char *buf;
- SECTOR sect;
- {
- return wrsects(dev, 1, buf, sect);
- }
-
-
- /*
- * Read sector(s) from dev.
- *
- * Input:
- * dev - device number (logical or physical).
- * num - number of sectors to read.
- * buf - buffer to write data read.
- * sect - starting sector number to read from.
- *
- * Return:
- * errnum - 0: if read is successful.
- * an error code: if read is unsuccessful.
- */
- rdsects(dev, num, buf, sect)
- int dev; /* device number (logical or physical) */
- UWORD num; /* number of sectors to read */
- char *buf;
- SECTOR sect; /* starting sector to read from */
- {
- int errnum;
-
- if (log2phys(&dev, §) < 0)
- return ERROR;
-
- ostack = Super(NULL);
- errnum = ideread(athead, atspt, sect, num, buf, (UWORD)dev);
- delay();
- Super(ostack);
-
- if (errnum > 0) {
- return ERROR;
- }
-
- return errnum; /* return the error code */
- }
-
-
- /*
- * Write sector(s) to dev.
- *
- * Input:
- * dev - device number (logical or physical).
- * num - number of sectors to write.
- * buf - buffer with data to be written.
- * sect - starting sector number to write to.
- *
- * Return:
- * errnum - 0: if write is successful.
- * an error code: if write is unsuccessful.
- */
- wrsects(dev, num, buf, sect)
- int dev; /* device number (logical or physical */
- UWORD num; /* number of sectors to write */
- char *buf; /* buffer with data to be written */
- SECTOR sect; /* starting sector to write to */
- {
- int errnum;
-
- if (log2phys(&dev, §) < 0)
- return ERROR;
-
- ostack = Super(NULL);
- errnum = idewrite(athead, atspt, sect, num, buf, (UWORD)dev);
- delay();
- Super(ostack);
-
- if (errnum > 0) {
- return ERROR;
- }
-
- return errnum;
- }
-
-
- /*
- * Zero range of sectors on dev.
- *
- */
- zerosect(dev, start, count)
- int dev;
- SECTOR start;
- UWORD count;
- {
- char *zbuf;
- int v;
- UWORD i;
-
- if ((zbuf = (char *)mymalloc(ZBUFSIZ)) <= 0)
- return ERROR;
-
- if (log2phys(&dev, &start) < 0) {
- free(zbuf);
- return ERROR;
- }
-
- fillbuf(zbuf, (long)ZBUFSIZ, 0L);
-
- while (count)
- {
- if (count > ZCOUNT)
- i = ZCOUNT;
- else i = count;
-
- if ((v = wrsects(dev, i, zbuf, start)) != 0)
- break;
- start += i;
- count -= i;
- }
- free(zbuf);
-
- return v;
- }
-